/* Universidade Federal de Campina Grande - UFCG
 * Centro de Engenharia El�trica e Inform�tica - CEEI
 * Departamento de Sistemas e Computa��o - DSC
 * Curso: Ci�ncia da Computa��o
 * Disciplina: Desenvolvimento de Aplica��es Corporativas Avan�adas (2008.1)
 * Professor: Jacques Philippe Sauv�
 * Monitor: Guilherme Mauro Germoglio Barbosa
 * Alunos: Daniel Souza Coelho
 * 		   Everton Leandro Galdino Alves
 * 		   Odilon Francisco de Lima Junior	
 */

package lembrete.core.beans;

import java.io.FileNotFoundException;
import java.util.ArrayList;

import lembrete.core.dao.Factory;
import lembrete.core.dao.UsuarioDao;
import lembrete.core.exceptions.ExcecaoBD;
import lembrete.core.exceptions.ExcecaoParametroInvalido;
import lembrete.core.exceptions.LembreteException;
/**
 * Essa classe representa um gerenciador de usuarios, o qual
 * eh responsavel pelas operacoes relacionadas aos usuarios.
 * 
 * @author Everton Leandro <br>
 *         Odilon Francisco <br>
 *         Daniel Coelho <br>
 * @version 1.0 
 */
public class GerenciadorDeUsuarios {


	private UsuarioDao usuarioDao = null;
	private static GerenciadorDeUsuarios gerenciador = null; 
	private Long logadosId;
	private Long entradasId;
		
	/**
	 * Metodo criador da classe.
	 */
	private GerenciadorDeUsuarios(){
		usuarioDao = Factory.createUsuarioDao();
		logadosId = 0L;
		entradasId = 0L;
    }
	
	/**
	 * Metodo que retorna uma instancia da classe GerenciadorDeUsuarios, seguindo o
	 * padrao Factory.
	 * 
	 * @return instantcia da classe GerenciadorDeUsuarios
	 */
	public static GerenciadorDeUsuarios getInstance() {
		if (gerenciador == null) {
            gerenciador = new GerenciadorDeUsuarios();
        }
        return gerenciador;
	}

	/**
	 * Inicia o banco de dados onde serao armazenados os dados
	 * do sistema.
	 * 
	 * @param nomeBD
	 * @throws ExcecaoBD
	 * @throws FileNotFoundException
	 */
	public void usarBancoDeDados(String nomeBD) throws ExcecaoBD, FileNotFoundException {
		usuarioDao.setBD(nomeBD);		
	}

	/**
	 * Metodo que retorna o valor de um atributo do usuario.
	 * 
	 * @param nomeAtrib
	 * @return valor do atributo pedido
	 */
	public String getUserAttribute(String email, String nomeAtrib) throws ExcecaoParametroInvalido, ExcecaoBD {
        Usuario us;
        try {
        	us = usuarioDao.procuraUsuario(email);
        	return us.getAtributo(nomeAtrib);
		} catch (Exception e) {
			throw new ExcecaoParametroInvalido("Usuario nao cadastrado.");
		}
        
	}

	/**
	 * Cadastra um usuario no sistema Lembrete.
	 * 
	 * @param email
	 * @param senha
	 * @param nome
	 * @throws LembreteException
	 * @throws ExcecaoBD
	 * @throws FileNotFoundException
	 */
	public void cadastraUsuario(String email, String senha, String nome) throws LembreteException, ExcecaoBD, FileNotFoundException {
		Usuario usuario = new Usuario(email, senha, nome);

		if (!usuarioEstaCadastrado(email)) {
			usuarioDao.adicionaUsuario(usuario);
		} else {
			throw new LembreteException("Conta com esse email ja existe.");
		}	
	}
	
	/**
	 * Verifica se o usuario esta cadastrado no sistema
	 * @param email email do usuario do sistema
	 * @return true se o usuario existir e false caso contrario
	 */
	public boolean usuarioEstaCadastrado(String email){
		try {
			usuarioDao.procuraUsuario(email);
		} catch (Exception e) {
			return false;
		}
		return true;
		
	}
	
	/**
	 * Remove todos os usuarios do sistema Lembrete.
	 * 
	 * @throws FileNotFoundException
	 * @throws ExcecaoBD
	 */
	public void removeTodosUsuarios() throws FileNotFoundException, ExcecaoBD {
		usuarioDao.limpaBD();
		Factory.createUsuarioDao().limpaBD();
	}

	/**
	 * Faz login de um usuario no sistema lembrete.
	 * 
	 * @param email
	 * @param senha
	 * @return id dos usuarios logados
	 * @throws LembreteException
	 * @throws ExcecaoBD
	 */
	public Usuario fazLogin(String email, String senha) throws LembreteException, ExcecaoBD {		
		try {
			Usuario us = usuarioDao.procuraUsuario(email);
			if (us.verificaSenha(senha)){
				setLogadosId(getLogadosId()+1);
				return us;
			}else throw new LembreteException("Login ou senha invalidos.");
		} catch (Exception e) {
			throw new LembreteException("Login ou senha invalidos.");
		}
	}
	
	/**
	 * Insere um contato na agenda do usuario.
	 * 
	 * @param email
	 * @param nome
	 * @param telefone
	 * @param aniversario
	 * @return id da entrada
	 * @throws LembreteException
	 * @throws ExcecaoBD
	 * @throws FileNotFoundException
	 * @throws ExcecaoParametroInvalido
	 */
	public Long insereEntrada(String email, String nome, String telefone, String aniversario) throws LembreteException, ExcecaoBD, FileNotFoundException, ExcecaoParametroInvalido {
		if (nome==null || nome.equals(""))
			throw new ExcecaoParametroInvalido("Falta o nome do usuario.");
		else if ((telefone==null || telefone.equals("")) && 
		(aniversario==null || aniversario.equals("")))
			throw new ExcecaoParametroInvalido("Atributos invalidos.");
		setEntradasId(getEntradasId()+1);
		usuarioDao.adicionaEntrada(email, nome, telefone, aniversario, getEntradasId());
		return getEntradasId();
	}

	/**
	 * Retorna o id dos usuarios que estao logados.
	 * 
	 * @return logadosId
	 */
	public Long getLogadosId() {
		return logadosId;
	}

	/**
	 * Atualiza os Id's dos usuarios logados no sistema.
	 * 
	 * @param logadosId
	 */
	public void setLogadosId(Long logadosId) {
		this.logadosId = logadosId;
	}

	/**
	 * Obtem o valor de um atributo de um contato do usuario.
	 * 
	 * @param email
	 * @param idContato
	 * @param nomeAtributo
	 * @return valor do atributo
	 * @throws ExcecaoBD
	 * @throws ExcecaoParametroInvalido
	 */
	public String getAtributoContato(String email, String idContato, String nomeAtributo) throws ExcecaoBD, ExcecaoParametroInvalido {
		return usuarioDao.buscaContato(email, idContato, nomeAtributo);
	}

	/**
	 * Metodo que retorna uma entrada como string.
	 * 
	 * @param emailUsuario
	 * @param idEntrada
	 * @return entrada como um String
	 * @throws ExcecaoBD
	 */
	public String visualizarEntrada(String emailUsuario, String idEntrada) throws ExcecaoBD {
		return usuarioDao.visualizarEntrada(emailUsuario,idEntrada);
	}

	/**
	 * Edita um campo de uma entrada na agenda do usuario.
	 * 
	 * @param emailUsuario
	 * @param idEntrada
	 * @param campoAntigo
	 * @param novoCampo
	 * @throws ExcecaoBD
	 * @throws ExcecaoParametroInvalido
	 * @throws FileNotFoundException
	 */
	public void editarEntrada(String emailUsuario, String idEntrada,
			String campoAntigo, String novoCampo) throws ExcecaoBD, ExcecaoParametroInvalido, FileNotFoundException {
		usuarioDao.editarEntrada(emailUsuario,idEntrada, campoAntigo,novoCampo);
		
	}

	/**
	 * Passa para o usuario o id do grupo que ele participara.
	 * 
	 * @param idGrupo
	 * @param gerenteEmail
	 * @throws ExcecaoBD
	 * @throws FileNotFoundException 
	 */
	public void conectaUsuarioGrupo(Long idGrupo, String gerenteEmail) throws ExcecaoBD, FileNotFoundException {
		usuarioDao.conectaUsuarioGrupo(idGrupo, gerenteEmail);
		
	}

	/**
	 * Obtem uma entrada a partir do seu Id.
	 * 
	 * @param idUsuario
	 * @param entradaId
	 * @return entrada pedida
	 * @throws ExcecaoBD
	 */
	public Entrada getEntrada(String idUsuario, String entradaId) throws ExcecaoBD {
		return usuarioDao.getEntrada(idUsuario,entradaId);
	}

	/**
	 * Obtem um usuario a partir do email.
	 * 
	 * @param gerenteEmail
	 * @return Usuario pedido
	 * @throws ExcecaoBD
	 */
	public Usuario getUsuario(String gerenteEmail) throws ExcecaoBD {
		return usuarioDao.procuraUsuario(gerenteEmail);
		
	}

	/**
	 * Salva as modificacoes feitas na agenda do usuario.
	 * 
	 * @throws FileNotFoundException
	 * @throws ExcecaoBD
	 */
	public void salvaModificacoes() throws FileNotFoundException, ExcecaoBD {
		usuarioDao.salvaModificacoes();
		
	}

	/**
	 * Exclui uma entrada de um grupo da agenda do usuario.
	 * 
	 * @param emailUsuario
	 * @param idGrupo
	 * @param idEntrada
	 * @throws FileNotFoundException
	 * @throws ExcecaoBD
	 */
	public void excluirEntrada(String emailUsuario, String idGrupo,
			String idEntrada) throws FileNotFoundException, ExcecaoBD {
		usuarioDao.excluirEntrada(emailUsuario, idGrupo, idEntrada);
		
	}

	/**
	 * O dono do grupo envia uma notificacao de compartilhamento do grupo
	 * para um usuario do sistema.
	 * 
	 * @param donoDoGrupo
	 * @param emailUsuario
	 * @param idGrupo 
	 * @throws ExcecaoBD
	 */
	public void enviarNotificacaoDeCompartilhamento(String donoDoGrupo, String emailUsuario, String idGrupo) throws ExcecaoBD {
		Usuario u = usuarioDao.procuraUsuario(emailUsuario);
		Usuario donoGrupo = usuarioDao.procuraUsuario(donoDoGrupo);
		notifiqueCompartilhamento(donoGrupo.getNome(), u, idGrupo);
	}

	/**
	 * Notifica um usuario do compartilhamento do grupo.
	 * 
	 * @param donoDoGrupo
	 * @param usuario
	 * @param idGrupo 
	 */
	private void notifiqueCompartilhamento(String donoDoGrupo,Usuario usuario, String idGrupo){
		String notificacaoCompartilhamento = "O usuario " + donoDoGrupo + " deseja compartilhar um grupo de sua agenda com voce."
												+ " Eh do seu interesse participar desse compartilhamento? (Caso positivo clique aki)";
		usuario.receberMensagem(notificacaoCompartilhamento, idGrupo);
	}

	/**
	 *  Obtem o usuario a partir de uma entrada.
	 *  
	 * @param idEntrada
	 * @return usuario
	 * @throws ExcecaoBD
	 */
	public Usuario getUsuarioPorEntrada(String idEntrada) throws ExcecaoBD {
		return usuarioDao.getUsuarioPorEntrada(idEntrada);
	}
	
	public void excluiEntrada(String idEntrada) throws ExcecaoBD, FileNotFoundException {
		usuarioDao.excluiEntrada(idEntrada);
	}

	
	public Long getEntradasId() { 
		return entradasId;
	}

	public void setEntradasId(Long entradasId) {
		this.entradasId = entradasId;
	}

	public ArrayList<Long> getGruposDoUsuario(String emailUsuario) throws ExcecaoBD {
		return getUsuario(emailUsuario).getAgenda().getGrupos();
		
	}

	public Long localizaEntrada(String email, String string) throws ExcecaoParametroInvalido, ExcecaoBD {
		return usuarioDao.procuraUsuario(email).localizaEntrada(string);
	}

	public ArrayList<Usuario> getUsuarios() {
		return usuarioDao.getusuarios();
	}

	public Long getIdGrupoPorMsg(String email, String descricao) throws ExcecaoBD {
		Usuario u = usuarioDao.procuraUsuario(email);
		return u.getIdGrupoPorMsg(descricao);
		
	}

	public void removeMsg(String email, String descricao) throws ExcecaoBD, FileNotFoundException {
		usuarioDao.removeMsg(email, descricao);
		
	}

}
